#include "Capture.h"
#include "common.h"
#include "CaptrueToFile.h"
#include "CaptureAndSend.h"
#include "ReceiveAndPlay.h"

#include <iostream>

using namespace std;

DWORD WINAPI ReceiveFilterThread(PVOID param)
{

	SOCKET sock = ::socket(AF_INET,SOCK_STREAM, 0);

	if(sock == INVALID_SOCKET)
	{
		std::cout<<"Create socket error"<<endl;
		return false;
	}

	SOCKADDR_IN bindAddress;
	bindAddress.sin_addr.s_addr = htonl(INADDR_ANY);
	bindAddress.sin_family = AF_INET;
	bindAddress.sin_port = htons(1115);

	if( bind(sock, (SOCKADDR*)&bindAddress, sizeof(bindAddress)) == -1)
	{
		cout<<"bind error"<<endl;
		return false;
	}

	if( listen(sock, SOMAXCONN) == -1)
	{
		cout<<"listen error"<<endl;
		return false;
	}
	while (true)
	{
		SOCKET clientSocket;
		SOCKADDR_IN clientAddress;
		clientAddress.sin_family = AF_INET;
		int addressLen = sizeof(clientAddress);
		clientSocket = accept(sock, (SOCKADDR*)&clientAddress, &addressLen);

		std::cout<<"New connection:"<<inet_ntoa(clientAddress.sin_addr)<<":"<<ntohs(clientAddress.sin_port)<<std::endl;

		ReceiveAndPlay* receiveAndPlay = new ReceiveAndPlay();
		receiveAndPlay->setSocket(clientSocket);
		receiveAndPlay->start();
// 		Sleep(5000);
// 		receiveAndPlay->stop();
	}

	return 0;
}

struct CaptureCommandResponseParam
{
	SOCKET sockFd;
	CaptureAndSend* captureAndSend;
};

DWORD WINAPI CaptureCommandResponseThread(PVOID param)
{
	CaptureCommandResponseParam* myParam = (CaptureCommandResponseParam*)param;
	SOCKET sockFd = myParam->sockFd;
	CaptureAndSend* captureAndSend = myParam->captureAndSend;
	delete myParam;

	while (true)
	{
		int controlCode;
		if (!getFourByte(sockFd, controlCode))
		{
			ErrorPrint("Get control code error");
			return 1;
		}
		if (controlCode == 1)
		{
			if(!captureAndSend->start())
			{
				ErrorPrint("Start capture and send error");
				return 1;
			}
		}
		else if (controlCode == 2)
		{
			if (!captureAndSend->pause())
			{
				ErrorPrint("Pause capture and send error");
				return 1;
			}
		}
	}
}

int main()
{
	WSAData wsaData;
	WORD version = MAKEWORD(2,2);
	WSAStartup(version, &wsaData);


	int choice = 0;
	while(true)
	{
		std::cout<<"Please choose the role:\n1:Server(Receive and play)\n2:Client(Capture and send)"<<endl;
		cin>>choice;
		if (choice == 1 || choice == 2)
		{
			break;
		}
	}

	if(choice == 1)
	{
		HANDLE playThread;
		playThread = CreateThread(
			NULL,
			0,
			ReceiveFilterThread,
			NULL,
			0,
			NULL);
		if (playThread == INVALID_HANDLE_VALUE)
		{
			ErrorPrint("Create thread error");
			return 1;
		}

	}
	else
	{
		std::string ipAddress = "127.0.0.1";
		unsigned short port = 1115;

		std::string inputIp;
		std::cout<<"Please input ip address:"<<std::endl;
		std::cin>>inputIp;
//		getline(std::cin, inputIp);
		if (inputIp != "")
		{
			ipAddress = inputIp;
		}



		SOCKET sockFd = socket(AF_INET, SOCK_STREAM, 0);
		if(sockFd == INVALID_SOCKET)
		{
			return 1;
		}

		SOCKADDR_IN desAddress;
		desAddress.sin_family = AF_INET;
		desAddress.sin_addr.s_addr = inet_addr(ipAddress.c_str());
		desAddress.sin_port = htons(port);

		int result = connect(sockFd, (SOCKADDR*)&desAddress, sizeof(desAddress));
		if(result == -1)
		{
			return 1;
		}

		CaptureAndSend* captureAndSend = CaptureAndSend::instance();
		if( !captureAndSend->setSocket(sockFd))
		{
			return 1;
		}

		CaptureToFile* captureToFile = CaptureToFile::instance();
		if (!captureToFile->start(L"test.mkv"))
		{
			return 1;
		}

// 		Sleep(10000);
// 
// 		captureToFile->stop();

		CaptureCommandResponseParam* param = new CaptureCommandResponseParam;
		param->sockFd = sockFd;
		param->captureAndSend = captureAndSend;

		HANDLE responseThread = CreateThread(
			NULL,
			0,
			CaptureCommandResponseThread,
			(LPVOID)param,
			0,
			NULL);


// 		Sleep(10000);
// 		captureAndSend->pause();
// 
// 		Sleep(10000);
// 
// 		if(!captureAndSend->start())
// 		{
// 			return 1;
// 		}
// 
// 		Sleep(10000);
// 		captureToFile->stop();
// 
// 		captureToFile->start(L"test2.mkv");
// 
// 		Sleep(10000);
// 		captureToFile->stop();
// 
// 		captureToFile->start(L"test3.mkv");
// 		captureAndSend->start(ipAddress, port);
	}

 	Sleep(INFINITE);

	return 0;
}
// 
// // int main()
// // {
// // 	boost::shared_ptr<CaptrueToFile> captureToFile = CaptrueToFile::instance();
// // 	captureToFile->start(L"test.avi");
// // 	Sleep(5000);
// // 	captureToFile->stop();
// // //	CaptureToFile(L"test.avi");
// // }
// 
// int main()
// {
// 	WSAData wsaData;
// 	WORD version = MAKEWORD(2,2);
// 	WSAStartup(version, &wsaData);
// 
// 	int choice = 0;
// 	while(true)
// 	{
// 		std::cout<<"Please choose the role:\n1:Server(Receive and play)\n2:Client(Capture and send)"<<endl;
// 		cin>>choice;
// 		if (choice == 1 || choice == 2)
// 		{
// 			break;
// 		}
// 	}
// 	
// 	std::string ipAddress = "192.168.18.62";
// 	unsigned short port = 1115;
// 
// 	if(choice == 1)
// 	{
// 		HANDLE playThread;
// 		playThread = CreateThread(
// 			NULL,
// 			0,
// 			ReceiveFilterThread,
// 			NULL,
// 			0,
// 			NULL);
// 		if (playThread == INVALID_HANDLE_VALUE)
// 		{
// 			ErrorPrint("Create thread error");
// 			return 1;
// 		}
// 
// 	}
// 	else
// 	{
// 		StartCaptureAndSend(ipAddress, port);
// 	}
// 
//  	Sleep(INFINITE);
// 
// // 	const WCHAR* fileName = L"test.avi";
// // 	if(!CaptureToFile(fileName))
// // 	{
// // 		cout<<"Capture to file error";
// // 		return 1;
// // 	}
// // 	Sleep(5000);
// // 	StopCaptureToFile();
// 	return 0;
// }